#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<Windows.h>
#pragma comment(lib,"Winmm.lib")

#define SCREEN_WIDTH  500//游戏窗口宽度
#define SCREEN_HEIGTH 700 //游戏窗口长度

#define PLANE_SIZE 50 //飞机大小

#define ENEMY_NUM 8 //敌机数量

#define ENEMY_SPEED 1.0 //敌机生成时间

#define BULLET_NUM 10 //子弹数量

typedef struct pos {
	int x;
	int y;
}POS; //坐标类型

typedef struct plane {
	POS planePos;//飞机坐标
	POS planeBullets[BULLET_NUM];//子弹坐标数组
	int bulletLen;//子弹存活数量
	int bulletSpeed;//子弹移动速度
}PLANE; //飞机类型

PLANE myPlane; //自己的飞机
PLANE enemyPlanes[ENEMY_NUM]; //敌机
int enemyPlaneLen; //当前敌机存活的数量
static time_t startTime, endTime; //时间差来控制飞机的移动
IMAGE img[3]; //贴图
int score = 0; //分数

void initGame();
void drawGame();
void updateGame();
void initEnemyPlane();
void destroyEnemyPlane();
void destroyBullet();
int areInierSecting(POS c1, POS c2, int radius);

int main() {

	loadimage(&img[0], "img/background.png", SCREEN_WIDTH, SCREEN_HEIGTH);
	loadimage(&img[1], "img/SmallPlane.png", PLANE_SIZE, PLANE_SIZE);
	loadimage(&img[2], "img/BigPlane.png", PLANE_SIZE, PLANE_SIZE);

	initGame();
	while (1) {
		drawGame();
		updateGame();
		Sleep(1000/60);
	}
    
	return 0;
}




void initGame() {
	initgraph(SCREEN_WIDTH, SCREEN_HEIGTH);
	score = 0;

	srand((unsigned)time(NULL));

	myPlane.bulletLen = 0;
	myPlane.bulletSpeed = 3;
	myPlane.planePos = { SCREEN_WIDTH / 2 - PLANE_SIZE / 2,SCREEN_HEIGTH - PLANE_SIZE };
	enemyPlaneLen = 0;

	startTime = time(NULL);
}

void drawGame() {
	BeginBatchDraw();//开始批量贴图
	putimage(0, 0, &img[0]);
	putimage(myPlane.planePos.x - PLANE_SIZE/2,myPlane.planePos.y - PLANE_SIZE/2, &img[2],SRCAND);//SRCAND参数可以将图片的白边（必须是白边）去除是图片与背景相融合

	for (int i = 0; i < enemyPlaneLen; i++) {
		putimage(enemyPlanes[i].planePos.x - PLANE_SIZE/2, enemyPlanes[i].planePos.y - PLANE_SIZE/2, &img[1],SRCAND);
	}//绘制敌机

	for (int i = 0; i < myPlane.bulletLen; i++) {
		solidcircle(myPlane.planeBullets[i].x, myPlane.planeBullets[i].y, PLANE_SIZE / 4);
	}//绘制子弹

	RECT rect = { 0,PLANE_SIZE,SCREEN_WIDTH,SCREEN_HEIGTH };//设置字符串绘制的指定矩形区域
	setbkmode(TRANSPARENT);//设置文字背景透明
	char str[30] = { 0 };
	sprintf(str, "score:%d", score);
	drawtext(str, &rect, DT_TOP | DT_CENTER);//绘制字符串

	EndBatchDraw();//结束批量贴图
}

void updateGame() {
	if (GetAsyncKeyState('W') & 0x8000) {
		myPlane.planePos.y -= 4;
	}
	if (GetAsyncKeyState('S') & 0x8000) {
		myPlane.planePos.y += 4;
	}
	if (GetAsyncKeyState('A') & 0x8000) {
		myPlane.planePos.x -= 4;
	}
	if (GetAsyncKeyState('D') & 0x8000) {
		myPlane.planePos.x += 4;
	}

	if (_kbhit()) {
		if (_getch() == ' ') {
			if (myPlane.bulletLen < BULLET_NUM) {
				PlaySound("img/bullet.wav", NULL, SND_FILENAME | SND_ASYNC | SND_NOWAIT);
				myPlane.planeBullets[myPlane.bulletLen] = myPlane.planePos;
				myPlane.bulletLen++;
			}
		}
	}
	for (int i = 0; i < enemyPlaneLen; i++) {
		enemyPlanes[i].planePos.y += 2;
	}

	for (int i = 0; i < myPlane.bulletLen; i++) {
		myPlane.planeBullets[i].y -= myPlane.bulletSpeed;
	}

	initEnemyPlane();
	destroyEnemyPlane();
	destroyBullet();
}

void initEnemyPlane() {
	endTime = time(NULL);
	double elapsedTime = difftime(endTime, startTime);
	if (elapsedTime >= ENEMY_SPEED) {
		if (enemyPlaneLen < ENEMY_NUM) {
			int x = (rand() % (SCREEN_WIDTH - 2 * PLANE_SIZE)) + PLANE_SIZE;
			int y = -PLANE_SIZE;

			enemyPlanes[enemyPlaneLen].planePos.x = x;
			enemyPlanes[enemyPlaneLen].planePos.y = y;

			enemyPlaneLen++;
		}
		startTime = endTime;
	}
}

void destroyEnemyPlane() {
	for (int i = 0; i < enemyPlaneLen; i++) {
		if (areInierSecting(myPlane.planePos, enemyPlanes[i].planePos, PLANE_SIZE)) {
			if (IDYES == MessageBox(GetHWnd(), "The game has ended. Would you like to restart the game?", "Prompt", MB_YESNO)) {
				initGame();
			}
			else {
				exit(0);
			}
		}

		if (enemyPlanes[i].planePos.y > SCREEN_HEIGTH) {
			for (int j = i; j < enemyPlaneLen; j++) {
				enemyPlanes[j] = enemyPlanes[j + 1];
			}
			enemyPlaneLen--;
			i--; //如果有飞机溢出屏幕，都要删除
		}
	}
}

void destroyBullet() {
	for (int i = 0; i < myPlane.bulletLen; i++) {
		for (int j = 0; j < enemyPlaneLen; j++) {
			if (areInierSecting(myPlane.planeBullets[i], enemyPlanes[j].planePos, PLANE_SIZE / 4 + PLANE_SIZE / 2)) {
				for (int x = i; x < myPlane.bulletLen; x++) {
					myPlane.planeBullets[x] = myPlane.planeBullets[x + 1];
				}
				for (int x = j; x < enemyPlaneLen; x++) {
					enemyPlanes[x] = enemyPlanes[x + 1];
				}
				enemyPlaneLen--;
				myPlane.bulletLen--;
				j--;
				score += 100;
			}
		}
		if (myPlane.planeBullets[i].y < 0) {
			for (int x = i; x < myPlane.bulletLen; x++) {
				myPlane.planeBullets[x] = myPlane.planeBullets[x + 1];
			}
			myPlane.bulletLen--;
			i--;
		}
	}
}

int areInierSecting(POS c1, POS c2, int radius) {
	return abs(c1.x - c2.x) <= radius && abs(c1.y - c2.y) <= radius;
}

